﻿using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Cmp;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Domain.LogDomain;
using Zocono.WCS.Domain.PlcBytesObject;
using Zocono.WCS.Domain.PlcConnectPoolDomain;
using Zocono.WCS.Domain.ScGetWMSTaskDomain;
using Zocono.WCS.Infrastructure.ApllicationDto.WmsModel;
using Zocono.WCS.Infrastructure.PlcCommon;

namespace Zocono.WCS.Domain.PlcWriteBoMangeDomain
{
    public class PlcWriteBoService : IPlcWriteBoService
    {
        private readonly IRunLogInfoService _IRunLogInfoService;
        private readonly IScGetWMSTaskService _IScGetWMSTaskService;
        private readonly IPlcConnectionPool _plcConnectionPoolService;

        public PlcWriteBoService(IPlcConnectionPool plcConnectionPoolService, IScGetWMSTaskService iScGetWMSTaskService, IRunLogInfoService runLogInfoService)
        {
            _plcConnectionPoolService = plcConnectionPoolService;
            _IScGetWMSTaskService = iScGetWMSTaskService;
            _IRunLogInfoService = runLogInfoService;
        }

        public async Task<bool> WCSSetSCPLCAsync(ZJNScMessageWriteWcsActionBO wcsActionBO)
        {
            //Sc写入Db
            PlcWriteDbInfo plcWriteDbInfo = await _IScGetWMSTaskService.ScGetPlcWriteDbInfoAsync("SC" + wcsActionBO.EquipmentCode.ToString(), wcsActionBO.ObjectType);
            //Sc使用Plc连接
            var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);

            if (plcservice == null)
            {
                throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
            }
            var bytes = wcsActionBO.Deserialize();
            bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);
            return flag;

        }

        public async Task<bool> WCSSetPlanerPLCAsync(PlanarGeneralWriteWcsAction wcsActionBO)
        {
            //Sc写入Db
            PlcWriteDbInfo plcWriteDbInfo = await _IScGetWMSTaskService.ScGetPlcWriteDbInfoAsync(wcsActionBO.EquipmentCode.ToString(), wcsActionBO.ObjectType);
            //Sc使用Plc连接
            PlcConnectionS7 plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);

            if (plcservice == null)
            {
                throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
            }
            var bytes = wcsActionBO.Deserialize();
            bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);
            return flag;
        }
        public async Task<bool> OperatePlanarPlcBoAsync(PlanarGeneralWriteWcsAction wcsActionBO)
        {
            //Sc写入Db
            PlcWriteDbInfo plcWriteDbInfo = await _IScGetWMSTaskService.ScGetPlcWriteDbInfoAsync(wcsActionBO.EquipmentCode.ToString(), wcsActionBO.ObjectType);
            //Sc使用Plc连接
            PlcConnectionS7 plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);

            if (plcservice == null)
            {
                throw new Exception($"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在");
            }
            var bytes = wcsActionBO.Deserialize();
            bool flag = await plcservice.WriteDbAsync(101, plcWriteDbInfo.DbStart, bytes);
            return flag;
        }

        /// <summary>
        /// 分容柜门打开报警
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public async Task<bool> DoorOpenAlarmAsync(List<CapacityDoorOpen> capacityDoorOpen)
        {
            RunLogInfo runLogInfo = new RunLogInfo();
            runLogInfo.RunType = "恒翼能分容柜开门报警";
            try
            {
                short isAlarm = 0;
                string equip = string.Empty;
                foreach (var item in capacityDoorOpen)
                {

                    isAlarm = (short)(item.IsOpen ? 1 : 0);
                    switch (item.AisleCode)
                    {
                        case "SC001":
                            equip = "SC2001"; break;
                        case "SC002":
                            equip = "SC2002"; break;
                        case "SC005":
                            equip = "SC2005"; break;
                        case "SC006":
                            equip = "SC2006"; break;
                        case "SC007":
                            equip = "SC2007"; break;
                        default:
                            break;
                    }
                   
                    runLogInfo.ContainerBarcode = equip;
                    runLogInfo.EquipmentCode = equip;

                    //Sc写入Db
                    PlcWriteDbInfo plcWriteDbInfo = await _IScGetWMSTaskService.ScGetPlcWriteDbInfoAsync(equip, "ZJNScMessageWriteWcsActionBO");
                    //Sc使用Plc连接
                    var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);

                    ZJNScMessageWriteWcsActionBO zjnScBo = new()
                    {
                        ObjectType = "ZJNScMessageWriteWcsActionBO",
                        Startcommand = false,
                        Alarmreset = false,
                        WCSfirecommand = false,
                        WCSPhotoFire = false,
                        WCSRgvFireHlper = false,
                        WCSDTSAlarm = false,
                        TimeReset = false,
                        Taskreset = false,

                        Jobnumber = 0,
                        Jobordercode = 0,
                        WCSpostingcompleted = 0,
                        StartlinefromPC = 0,
                        StartlayerfromPC = 0,
                        StartcolumnfromPC = 0,
                        TargetlinefromPC = 0,
                        TargetcolumnfromPC = 0,
                        TargetlayerfromPC = 0,
                        yuliu8 = 0,
                        yuliu9 = isAlarm,//1门开报警
                        yuliu10 = 0,
                        yuliu11 = 0,
                        yuliu12 = 0,

                        EquipmentCode = equip.ToString().Substring(2).ToInt32()
                };

                    if (plcservice == null)
                    {
                        runLogInfo.RunLog = $"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在，掉线";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    }
                    var bytes = zjnScBo.Deserialize();
                    bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);
                    if (!flag)
                    {
                        runLogInfo.RunLog = $"PLC写入Id:{plcWriteDbInfo.PlcConnectionId}失败！";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        return flag;
                    }
                    else
                    {
                        runLogInfo.RunLog = $"{JsonConvert.SerializeObject(zjnScBo)} 报文写入成功！";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    }
                }
                return true;

            }
            catch(Exception ex)
            {
                runLogInfo.ContainerBarcode = "";
                runLogInfo.EquipmentCode = "";
                runLogInfo.RunLog = $"PLC写入恒翼能分容柜开门报警失败！ex{ex.Message}";
                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                return false;
            }
        }

        public async Task<bool> WCSSetPlanerPLCWriteAsync(HynReturnState returnState)
        {
            RunLogInfo runLogInfo = new RunLogInfo();
            runLogInfo.RunType = "恒翼能上报设备状态";
            try
            {
                int isAlarm = returnState.StateCode;
                string equip = string.Empty;
                string returnEq = returnState.EquipmentCode;
                if(returnEq == "P004788")
                {
                    equip = "250017";
                }
                else if (returnEq == "P004787")
                {
                    equip = "250019";
                }
                else if (returnEq == "P004786")
                {
                    equip = "250021";
                }
                else if (returnEq == "P004785")
                {
                    equip = "250009";
                }
                else if (returnEq == "P004784")
                {
                    equip = "250011";
                }
                else if (returnEq == "P004783")
                {
                    equip = "250013";
                }
                else if (returnEq == "P004782")
                {
                    equip = "250001";
                }
                else if (returnEq == "P004781")
                {
                    equip = "250003";
                }
                else if (returnEq == "P004780")
                {
                    equip = "250005";
                }
                else if (returnEq == "P004807")
                {
                    equip = "250002";
                }
                else if (returnEq == "P004808")
                {
                    equip = "250004";
                }
                else if (returnEq == "P004809")
                {
                    equip = "250006";
                }
                else if (returnEq == "P004813")
                {
                    equip = "100014";
                }
                else if (returnEq == "P004812")
                {
                    equip = "100010";
                }
                else if (returnEq == "P004811")
                {
                    equip = "100006";
                }
                else if (returnEq == "P004810")
                {
                    equip = "100002";
                }
                else
                {
                    equip = returnEq;
                }

                runLogInfo.ContainerBarcode = equip;
                runLogInfo.EquipmentCode = equip;

                //获取读取DB配置
                PlcWriteDbInfo plcWriteDbInfo = await _IScGetWMSTaskService.ScGetPlcWriteDbInfoAsync(equip, "PlanarGeneralWriteWcsHynnStateAction");
                //使用Plc连接
                var plcservice = _plcConnectionPoolService.S7GetWritePlcConnection(plcWriteDbInfo.PlcConnectionId);

                PlanarGeneralWriteWcsHynnStateAction plWriteBo = new PlanarGeneralWriteWcsHynnStateAction(
                        plcWriteDbInfo.PlcConnectionId,
                        plcWriteDbInfo.ID,
                        plcWriteDbInfo.DbCode,
                        plcWriteDbInfo.DbStart,
                        "PlanarGeneralWriteWcsHynnStateAction",
                        isAlarm.ToByte());

                if (plcservice == null)
                {
                    runLogInfo.RunLog = $"PLC连接Id:{plcWriteDbInfo.PlcConnectionId}不存在，掉线";
                    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                }
                var bytes = plWriteBo.Deserialize();
                bool flag = await plcservice.WriteDbAsync(plcWriteDbInfo.DbCode, plcWriteDbInfo.DbStart, bytes);
                if (!flag)
                {
                    runLogInfo.RunLog = $"PLC写入Id:{plcWriteDbInfo.PlcConnectionId}失败！";
                    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    return flag;
                }
                else
                {
                    runLogInfo.RunLog = $"{JsonConvert.SerializeObject(plWriteBo)} 报文写入成功！";
                    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                }
                return true;
            }
            catch (Exception ex)
            {
                runLogInfo.ContainerBarcode = "";
                runLogInfo.EquipmentCode = returnState.EquipmentCode;
                runLogInfo.RunLog = $"PLC写入恒翼能上报设备状态失败！ex{ex.Message}";
                await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                return false;
            }
        }
    }
}
